package cn.jbooter.shiro.autoconfigure.config;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.Filter;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.web.filter.DelegatingFilterProxy;

import cn.jbooter.coms.exceptions.FrameworkException;
import cn.jbooter.shiro.autoconfigure.properties.IShiroProperties;

/**
 * Shiro rememberMe配置
 * @author HeJian
 *
 */
public class ShiroWebConfiguration {
	private static final Logger logger = LoggerFactory.getLogger(ShiroWebConfiguration.class);
	
	@Autowired
	protected IShiroProperties shiroProperties;
	@Autowired(required = false)
	protected List<CustomShiroFilterDefinition> customShiroFilterDefinitions;
	@Autowired
	protected SecurityManager securityManager;
	
	/**
	 * FilterRegistrationBean shiro web.xml 过滤器
	 * 
	 * @return
	 */
	@Bean(name = "filterShiroFilterRegistrationBean")
	public FilterRegistrationBean filterShiroFilterRegistrationBean() {
		FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
		filterRegistration.setFilter(new DelegatingFilterProxy("shiroFilter"));
		filterRegistration.setName("shiroFilter");
		filterRegistration.setEnabled(true);
		filterRegistration.addInitParameter("targetFilterLifecycle", "true");
		filterRegistration.addUrlPatterns(shiroProperties.getUrlPattern());
		return filterRegistration;
	}

	/**
	 * shiro filter
	 * 
	 * @return
	 */
	@Bean(name = "shiroFilter")
	protected ShiroFilterFactoryBean shiroFilter() {
		ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
		filterFactoryBean.setLoginUrl(shiroProperties.getLoginUrl());
		filterFactoryBean.setSuccessUrl(shiroProperties.getSuccessUrl());
		filterFactoryBean.setUnauthorizedUrl(shiroProperties.getUnauthorizedUrl());
		filterFactoryBean.setSecurityManager(securityManager);

		// 组装自定义shiro过滤器
		if (customShiroFilterDefinitions != null && customShiroFilterDefinitions.size() > 0) {
			Map<String, Filter> filters = new LinkedHashMap<>();
			for (CustomShiroFilterDefinition df : customShiroFilterDefinitions) {
				if (df != null && df.getCustomShiroFilterMap() != null && !df.getCustomShiroFilterMap().isEmpty()) {
					filters.putAll(df.getCustomShiroFilterMap());
				}
			}
			if (filters != null && !filters.isEmpty()) {
				filterFactoryBean.setFilters(filters);
			}
		}else {
			logger.info(">>>>>> not find custome shiro filter .");
		}

		// 组装配置的拦截器链
		Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
		List<String> filterChainDefinitions = shiroProperties.getFilterChainDefinitions();
		if (filterChainDefinitions != null && filterChainDefinitions.size() > 0) {
			for (String chain : filterChainDefinitions) {
				String[] split = chain.split("=");
				if (split.length != 2)
					throw new FrameworkException("ishiro.filterChainDefinitions中配置的" + chain + "格式错误,无法解析!");
				filterChainDefinitionMap.put(split[0].trim(), split[1].trim());
			}
		}
		filterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

		return filterFactoryBean;
	}
}
